

import {
  WebSocketGateway, // 导入WebSocketGateway装饰器，用于定义WebSocket网关
  WebSocketServer, // 导入WebSocketServer装饰器，用于注入WebSocket服务器实例
  SubscribeMessage, // 导入SubscribeMessage装饰器，用于定义处理WebSocket消息的方法
  ConnectedSocket, // 导入ConnectedSocket装饰器，用于获取连接的WebSocket客户端
  MessageBody, // 导入MessageBody装饰器，用于获取消息体
} from '@nestjs/websockets';

import { Socket, Server } from 'socket.io'; // 导入Socket.IO的Socket类型
// 导入远程控制服务
import { RemoteControlService } from './remote-control.service';
@WebSocketGateway(8113, {
  // 允许跨域
  cors: {
    origin: '*', // 允许所有来源
  },
  // 定义命名空间
  namespace: 'control', 
})

export class RemoteControlGateway {

  // 注入WebSocket服务器实例，需要向所有客户端广播消息时使用
  @WebSocketServer() server: Server;
   // 定义一个设备类型的字段，用于区分不同类型的设备

  private deviceType = 'linux'; // 默认设备类型为 Linux

   // 构造函数，注入远程控制服务
  constructor(private remoteControlService: RemoteControlService) {}

  // 当客户端连接时触发
  handleConnection(client: Socket) {
      console.log(`客户端接入: ${client.id}`);
      // 初始化 SSH 会话
      this.remoteControlService.initializeSession(client.id);
  }

  // 当客户端断开连接时触发
  handleDisconnect(client: Socket) {
    console.log(`客户端断开: ${client.id}`);
  }


   // 处理启动终端会话的请求,传入主机地址、用户名和密码、设备类型
   @SubscribeMessage('startTerminalSession')
   async handleStartTerminalSession(
   @MessageBody()data: { host: string; username: string; password: string; type: string },
   @ConnectedSocket() client: Socket,
   ) {
     const clientId = client.id; //获取客户端ID
     this.deviceType = data.type; //设置设备类型,linux,device
     try {
       // 启动 SSH 会话
       const message = await this.remoteControlService.startSSHSession(
         data.host,
         data.username,
         data.password,
         clientId,
         data.type, // 传递设备类型到服务层
       );
       // 获取 SSH 会话的 shell 流
       const shellStream = this.remoteControlService.getShellStream(clientId);
       if (shellStream) {
         // 监听 shell 流的 data 事件,当主机SSH会话有输出时触发
         shellStream.on('data', (data: Buffer) => {
           // 确保发送的是字符串格式的数据
           console.log(data,"data");
           console.log(data.toString('utf8'));
           
           client.emit('terminalData', data.toString('utf8'));
         });
       }
       // 发送启动终端会话的成功消息
       client.emit('terminalSessionStarted', { message, clientId });
     } catch (error) {
       // 发送启动终端会话的失败消息
       client.emit('terminalSessionError', error.message);
       // 如果设备类型是路由器交换机，发送退出命令
       if (this.deviceType === 'device') {
         await this.remoteControlService.sendExitCommands(clientId);
       } else {
         // 执行断开设备连接
         this.remoteControlService.disconnect(clientId);
       }
     }
   }
  
   // 处理终端输入,传入客户端ID和输入的命令
   @SubscribeMessage('input')
   async handleInput(
     @MessageBody() data: { clientId: string; input: string },
     @ConnectedSocket() client: Socket,
   ) {
     if (client.disconnected) {
       console.log(`客户端 ${client.id} 已断开连接，停止处理输入`);
       return;
     }
     try {
       // 根据客户端 ID 获取 SSH 会话的 shell 流
       const shellStream = this.remoteControlService.getShellStream(
         data.clientId,
       );
       // 如果 shell 流存在且可写,将输入写入 shell 流
       if (shellStream && shellStream.writable) {
          console.log(data.input,"data.input");
         // 检查输入是否为退格键，并发送正确的字符
         shellStream.write(data.input);
       } else {
         // 如果 shell 流不存在或不可写,发送错误消息
         client.emit(
           'terminalSessionError',
           'Shell终端不可用,请检查是否已启动终端会话.',
         );
         // 如果设备类型是路由器交换机，发送退出命令
         if (this.deviceType === 'device') {
           await this.remoteControlService.sendExitCommands(data.clientId);
         } else {
           // 执行断开设备连接
           this.remoteControlService.disconnect(data.clientId);
         }
       }
     } catch (error) {
       console.log('处理终端输入时发生错误:', error);
     }
   }
  
   // 处理断开终端连接的请求,传入客户端ID
   @SubscribeMessage('disconnectTerminal')
   async handleDisconnect1(
     @MessageBody() clientId: string,
     @ConnectedSocket() client: Socket,
   ) {
     console.log('进入 sendExitCommands 断开设备的方法:', clientId);
     // 如果设备类型是路由器交换机，发送退出命令
     if (this.deviceType == 'device') {
       client.emit('terminalDisconnected', '设备终端已断开');
       const message = await this.remoteControlService.sendExitCommands(
         clientId,
       );
       console.log('执行 sendExitCommands 设备命令之后：', message);
     } else {
       client.emit('terminalDisconnected', '系统终端已断开');
       // 执行断开设备连接
       this.remoteControlService.disconnect(clientId);
     }
   }

   
 }



